from typing import Union
import time

"""
打印格式规范：
"""

def pct_line(pct: float) -> str:
    """进度条显示"""
    pct = int(pct / 4)
    completed = '\u2588' * pct
    line_else = '\u2592' * (25 - pct)
    show = completed + line_else
    return show


def pct_num(pct: float) -> str:
    """百分比显示"""
    num = '%.2f' % pct
    show = num + '%'
    return show

# 动画序列，改进时改style装填对象即可  https://unicode-table.com/cn
s_line = ['-', '—', '\u2572', '\\', '|', '/', '—', '-', '·', '-', '—', '\\', '|', '/', '\u2571', '—', '-', '·']
s_baseline = ['-', '\\', '|', '/']
s_baseline_slow = ['-', '-', '-', '\\', '\\', '\\', '|', '|', '|', '/', '/', '/']
s_beatball = ['·', '-', '—', '·', '.',  '\u203F', '_', '.']
def pct_icon(pct: float) -> str:
    """简易动画标签"""
    style = s_baseline_slow
    step = int(pct) % len(style)
    show = ' ' + style[step]
    return show


class PctShow:
    """
    -打印类:使用案例
        p = PctShow(50000, 'Mineways')\n
        for i in range(50000):
            p.update(i)
    -同时可对显示标签进行控制，一切标签均可设定为False进行舍去
        tag(标签名)|icon(小动画)|line(进度条)|pct(百分比)|detail(详细数字)
        其中标签名若进行设置，直接传入即可
        特殊：fix(修正值) -> 默认为0，百分比计算时对total修正
    """
    style = {  # 打印格式设置，此处为各元素定长设置
        'tag': 0,
        'icon': 4,
        'line': 28,
        'pct': 9,
        'detail': 12,
    }

    def __init__(self, total,
                 tag: Union[bool, str] = False,
                 line: bool = True,
                 detail: bool = True,
                 pct: bool = True,
                 icon: bool = True,
                 fix: int = 0):

        self.total = total
        self.fix = fix
        self.base = 0
        self.tag = tag

        self.icon = icon
        self.line = line
        self.detail = detail
        self.pct = pct

        self.start = time.time()     # 时间标签

    def update(self, base):
        self.base = base + 1  # 仅考虑通配情况下，for循环(0,100)为0至99，+1使其显示正确
        self.show()

    def endl(self, num=1):
        style = '/'  # 格式符号
        n = 25       # 格式数量
        finish = time.time() - self.start
        avg_time = finish/num
        content = '总计时间：%.2fs\t平均任务时间：%.2fs' % (finish, avg_time)
        show = style*n + content + style*n
        print('\n'+show+'\n')

    def show(self):
        percentage = self.base * 100 / (self.total + self.fix)
        if percentage > 99.9:
            percentage = 100
            self.base = self.total

        show = {}
        if self.tag:  # 前置标签
            show['tag'] = self.tag
        if self.icon:  # 动态显示图标
            show['icon'] = pct_icon(percentage)  # self.base
        if self.line:  # 进度条
            show['line'] = pct_line(percentage)
        if self.pct:  # 百分比
            show['pct'] = pct_num(percentage)
        if self.detail:  # 任务进度
            show['detail'] = f'{self.base}/{self.total}'

        s = ''
        for k, v in show.items():
            s += "{:^{parm}}".format(v, parm=self.style[k])
        print('\r', s, end='')
